﻿using BigEgg.Framework.Foundation;
using BigEgg.Framework.Foundation.Validations;
using FMStudio.Documents.TemplateDocument.Properties;
using System;
using System.ComponentModel.DataAnnotations;
using System.Xml.Serialization;

namespace FMStudio.Documents.TemplateDocument.Models
{
    public class TemplateInformation : ValidationModel
    {
        #region Fields
        private string name;
        private string description;
        private string icon;
        private int sortOrder;
        private string defaultName;
        private bool provideDefaultName;
        private string requiredVersion;
        private int numberOfParentCategoriesToRollUp;
        private bool enableLocationField;
        private bool enableLocationBrowser;
        #endregion


        public TemplateInformation(string name)
        {
            if (name == null) { throw new ArgumentNullException("name"); }

            this.name = name;
            this.description = name;
            this.icon = string.Empty;
            this.sortOrder = 1;
            this.defaultName = name;
            this.provideDefaultName = true;
            this.requiredVersion = "1.0";
            this.numberOfParentCategoriesToRollUp = 0;
            this.enableLocationField = true;
            this.enableLocationBrowser = true;
        }

        public TemplateInformation()
            : this(string.Empty)
        {
        }


        #region Properties
        /// <summary>
        /// Gets or sets the template's name.
        /// </summary>
        [XmlElement(IsNullable = false, Order = 1)]
        [Required(
            ErrorMessageResourceName = "TemplateInformationNameMandatory", 
            ErrorMessageResourceType = typeof(Resources))]
        public string Name
        {
            get { return this.name; }
            set
            {
                if (this.name != value)
                {
                    this.name = value;
                    RaisePropertyChanged("Name");
                }
            }
        }

        /// <summary>
        /// Gets or sets the template's description.
        /// </summary>
        [XmlElement(IsNullable = false, Order = 2)]
        [Required(
            AllowEmptyStrings = true, 
            ErrorMessageResourceName = "TemplateInformationDescriptionMandatory", 
            ErrorMessageResourceType = typeof(Resources))]
        public string Description
        {
            get { return this.description; }
            set
            {
                if (this.description != value)
                {
                    this.description = value;
                    RaisePropertyChanged("Description");
                }
            }
        }

        /// <summary>
        /// Gets or sets the path and name of the icon.
        /// </summary>
        [XmlElement(IsNullable = false, Order = 3)]
        [IsPathRooted(
            ErrorMessageResourceName = "TemplateInformationIconPathRooted", 
            ErrorMessageResourceType = typeof(Resources))]
        [Required(
            ErrorMessageResourceName = "TemplateInformationIconMandatory",
            ErrorMessageResourceType = typeof(Resources))]
        public string Icon
        {
            get { return this.icon; }
            set
            {
                if (this.icon != value)
                {
                    this.icon = value;
                    RaisePropertyChanged("Icon");
                }
            }
        }

        /// <summary>
        /// Gets or sets the sort order of the template.
        /// </summary>
        [XmlElement(Order = 4)]
        [Range(
            1, 65536,
            ErrorMessageResourceName="TemplateInformationSortOrderRange", 
            ErrorMessageResourceType=typeof(Resources))]
        public int SortOrder
        {
            get { return this.sortOrder; }
            set
            {
                if (this.sortOrder != value)
                {
                    this.sortOrder = value;
                    RaisePropertyChanged("SortOrder");
                }
            }
        }

        /// <summary>
        /// Gets or sets the default name shows in the dialog.
        /// </summary>
        [XmlElement(Order = 5)]
        [RequiredIf(
            "ProvideDefaultName", true, 
            ErrorMessageResourceName = "TemplateInformationDefaultNameMandatory", 
            ErrorMessageResourceType = typeof(Resources))]
        public string DefaultName
        {
            get { return this.defaultName; }
            set
            {
                if (this.defaultName != value)
                {
                    this.defaultName = value;
                    RaisePropertyChanged("DefaultName");
                }
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether provide the default name.
        /// </summary>
        [XmlElement(Order = 6)]
        public bool ProvideDefaultName
        {
            get { return this.provideDefaultName; }
            set
            {
                if (this.provideDefaultName != value)
                {
                    this.provideDefaultName = value;
                    RaisePropertyChanged("ProvideDefaultName");
                }
            }
        }

        /// <summary>
        /// Gets or sets the version that this template can used.
        /// </summary>
        [XmlElement(Order = 7)]
        [Required(
            ErrorMessageResourceName = "TemplateInformationRequiredVersionMandatory", 
            ErrorMessageResourceType = typeof(Resources))]
        public string RequiredVersion
        {
            get { return this.requiredVersion; }
            set
            {
                if (this.requiredVersion != value)
                {
                    this.requiredVersion = value;
                    RaisePropertyChanged("RequiredVersion");
                }
            }
        }

        /// <summary>
        /// Gets or sets the number of parent categories to roll up.
        /// </summary>
        [XmlElement(Order = 8)]
        [Range(
            0, 255,
            ErrorMessageResourceName = "TemplateInformationNumberOfParentCategoriesToRollUpGreaterThan", 
            ErrorMessageResourceType = typeof(Resources))]
        public int NumberOfParentCategoriesToRollUp
        {
            get { return this.numberOfParentCategoriesToRollUp; }
            set
            {
                if (this.numberOfParentCategoriesToRollUp != value)
                {
                    this.numberOfParentCategoriesToRollUp = value;
                    RaisePropertyChanged("NumberOfParentCategoriesToRollUp");
                }
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether enable the location field.
        /// </summary>
        [XmlElement(Order = 9)]
        public bool EnableLocationField
        {
            get { return this.enableLocationField; }
            set
            {
                if (this.enableLocationField != value)
                {
                    this.enableLocationField = value;
                    RaisePropertyChanged("EnableLocationField");
                }
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether enable location browser button.
        /// </summary>
        [XmlElement(Order = 10)]
        public bool EnableLocationBrowser
        {
            get { return this.enableLocationBrowser; }
            set
            {
                if (this.enableLocationBrowser != value)
                {
                    this.enableLocationBrowser = value;
                    RaisePropertyChanged("EnableLocationBrowser");
                }
            }
        }
        #endregion
    }
}
